import numpy as np
import random
from PIL import Image
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['SimHei']  # 步骤一（替换sans-serif字体）
plt.rcParams['axes.unicode_minus'] = False  # 步骤二（解决坐标轴负数的负号显示问题）


class Hopfield:
    def __init__(self):
        self.one = [-1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1,
                    -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1,
                    1, -1,
                    -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1,
                    1, -1,
                    -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1]
        self.two = [1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1,
                    -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1,
                    -1, -1, 1,
                    1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1,
                    -1, 1,
                    1, 1, 1, 1, 1, 1, 1, -1, -1]
        self.k = 0.2
        self.one = np.array(self.one).reshape((10, 10))
        self.two = np.array(self.two).reshape((10, 10))
        self.ONE = np.array(self.one).reshape((1, 100))
        self.TWO = np.array(self.two).reshape((1, 100))
        self.W = np.matmul(self.ONE.T, self.ONE) + np.matmul(self.TWO.T, self.TWO) - 2 * np.identity(100)

        self.NoiseONE = None
        self.NoiseTWO = None
        self.ONE = None
        self.TWO = None
    def F(self, X):
        X = np.heaviside(X, 1)
        return X

    def Noise(self, X):
        rownumber = X.shape[0]
        listnumber = X.shape[1]
        N = rownumber * listnumber
        Changenumber = int(N * self.K)  # 取整
        # 将数组展平
        X = X.reshape(1, N)
        # 在0-(N-1)中 随机取Changenumber个数字
        a = [random.randint(0, N - 1) for i in range(Changenumber)]
        for i in a:
            value = X[0, i]
            if value == -1:
                X[0, i] = 1
            else:
                X[0, i] = -1
        return X

    def calculate(self):

        self.NoiseONE = self.Noise(self.ONE)
        self.NoiseTWO = self.Noise(self.TWO)
        print(self.NoiseONE.reshape(10, 10))
        print(self.NoiseTWO.reshape(10, 10))
        self.ONE = 2 * np.matmul(self.W, self.NoiseONE.T).reshape((10, 10)) - 1
        self.TWO = 2 * np.matmul(self.W, self.NoiseTWO.T).reshape((10, 10)) - 1
        print(self.F(self.ONE))
        print(self.F(self.TWO))

a = Hopfield()

Image_one = Image.fromarray(256 * a.one)  # 数字1参考数组
Image_two = Image.fromarray(256 * a.two)  # 数字2参考数组
Image_NoiseONE = Image.fromarray(256 * a.NoiseONE.reshape(10, 10))  # 噪声数字1参考数组
Image_NoiseTWO = Image.fromarray(256 * a.NoiseTWO.reshape(10, 10))  # 噪声数字2参考数组
Image_ONE = Image.fromarray(256 * a.ONE)  # 数字1识别数组
Image_TWO = Image.fromarray(256 * a.TWO)  # 数字2识别数组


plt.figure()
plt.suptitle("噪声为%s" % a.K)
plt.subplot(3, 2, 1)
plt.title("数字1")
plt.xticks([])
plt.yticks([])
plt.imshow(Image_one)

plt.subplot(3, 2, 2)
plt.title("数字2")
plt.xticks([])
plt.yticks([])
plt.imshow(Image_two)

plt.subplot(3, 2, 3)
plt.title("噪声数字1")
plt.xticks([])
plt.yticks([])
plt.imshow(Image_NoiseONE)

plt.subplot(3, 2, 4)
plt.title("噪声数字2")
plt.xticks([])
plt.yticks([])
plt.imshow(Image_NoiseTWO)

plt.subplot(3, 2, 5)
plt.title("识别数字1")
plt.xticks([])
plt.yticks([])
plt.imshow(Image_ONE)

plt.subplot(3, 2, 6)
plt.title("识别数字2")
plt.xticks([])
plt.yticks([])
plt.imshow(Image_TWO)

plt.tight_layout()
# plt.savefig('/Users/Monks/Desktop/计算智能/noise=%s.png'%K,dpi=300)
plt.show()
